#include <fmt/core.h>
#include <rapidjson/document.h>
#include <rapidjson/filewritestream.h>
#include <rapidjson/pointer.h>
#include <rapidjson/prettywriter.h>
#include <rapidjson/rapidjson.h>
#include <rapidjson/schema.h>
#include <rapidjson/writer.h>

#include <cstdio>
#include <memory>
#include <string>

#include "cppguide/util/log_util.h"
#include "doctest/doctest.h"
#include "testhelper.hpp"

TEST_SUITE("test_common") {
    TEST_CASE("test_common_one") {
        std::shared_ptr<spdlog::logger> log = cppguide::LogUtil::getLogger("test");
        SPDLOG_LOGGER_INFO(log, fmt::format("test_common_one start"));

        /* 解析 json 文件 */
        std::string jsonPath = "janna.taskbuttons.json";
        auto        jsonr    = TestHelper::getInstance()->readTextFile(jsonPath);
        CHECK_MESSAGE(jsonr.ok(), fmt::format("文件:{} 打开失败", jsonPath));
        CHECK_MESSAGE(!jsonr.data.empty(), fmt::format("文件:{} 内容为空", jsonPath));
        rapidjson::Document jsonDoc;
        jsonDoc.Parse(jsonr.data.c_str());
        CHECK_MESSAGE(!jsonDoc.HasParseError(), fmt::format("文件:{} 解析失败", jsonPath));

        /* pointer */
        // 获取 id
        auto idValue = rapidjson::Pointer("/id").Get(jsonDoc);
        if (idValue && idValue->IsString()) {
            SPDLOG_LOGGER_INFO(log, fmt::format("id:{}", idValue->GetString()));
        } else {
            SPDLOG_LOGGER_ERROR(log, fmt::format("获取id失败"));
        }

        // 修改 id
        idValue->SetString("janna.core:1.0.0");

        // subscribe 添加一项
        // 获取 subscribe
        auto subscribeValue = rapidjson::Pointer("/subscribe").Get(jsonDoc);
        if (!subscribeValue || !subscribeValue->IsArray()) {
            SPDLOG_LOGGER_ERROR(log, fmt::format("获取 subscribe 失败"));
        }

        // 创建 subscribe 子项
        rapidjson::Value anotherSubscribe(rapidjson::kObjectType);
        anotherSubscribe.AddMember("source", "janna", jsonDoc.GetAllocator());
        anotherSubscribe.AddMember("topic", "echo-core", jsonDoc.GetAllocator());
        subscribeValue->GetArray().PushBack(anotherSubscribe, jsonDoc.GetAllocator());

        // 输出
        FILE* fp = fopen(jsonPath.c_str(), "w");  // 非 windows 平台使用 "w", windows 平台使用 "wb"
        CHECK_MESSAGE(fp, fmt::format("文件:{} 创建失败", jsonPath));
        char                                                writeBuffer[65536];
        rapidjson::FileWriteStream                          os(fp, writeBuffer, sizeof(writeBuffer));
        rapidjson::PrettyWriter<rapidjson::FileWriteStream> writer(os);
        jsonDoc.Accept(writer);
        fclose(fp);

        SPDLOG_LOGGER_INFO(log, fmt::format("test_common_one end"));
    }
}